﻿using Microsoft.AspNetCore.Http;

namespace Catalog.API.Products.LockProduct;


public record LockProductCommand(Guid OrderId, string OrderName, Guid ProductId, string ProductName, decimal Qty)
    : ICommand<LockProductResult>;
public record LockProductResult(bool IsOk, Guid RecordId);

public class LockProductCommandValidator : AbstractValidator<LockProductCommand>
{
    public LockProductCommandValidator()
    {
        RuleFor(command => command.OrderId).NotEmpty().WithMessage("OrderId is required");
        RuleFor(command => command.ProductId).NotEmpty().WithMessage("Product ID is required");
        RuleFor(command => command.Qty).GreaterThan(0).WithMessage("Qty must greater than 0");
    }
}

public class LockProductCommandHandler
    (IDocumentSession session)
    : ICommandHandler<LockProductCommand, LockProductResult>
{
    public async Task<LockProductResult> Handle(LockProductCommand command, CancellationToken cancellationToken)
    {
        var product = await session.LoadAsync<Product>(command.ProductId, cancellationToken);

        if (product is null)
        {
            throw new ProductNotFoundException(command.ProductId);
        }

        product.LockedQuantity += command.Qty;
        product.StockQuantity -= command.Qty;
        if (product.StockQuantity <= 0)
        {
            throw new Exception("Product is not avilable!");
        }
        session.Update(product);

        var record = new ProductLockRecord {
            Status = 0,
            ProductId = command.ProductId,
            CreatedTime = DateTime.Now,
            OrderId = command.OrderId,
            OrderName = command.OrderName,
            ProductName = command.ProductName,
            Qty = command.Qty,
        };
        session.Store<ProductLockRecord>(record);

        await session.SaveChangesAsync(cancellationToken);

        return new LockProductResult(true, record.Id);
    }
}



